SwiftUI的動畫功能非常強大,非常容易就可以實做出想要的動畫,先來看以下的例子:
@State var isShowText = false
var body: some View {
Text("Hello, World!")
.padding()
.opacity(isShowText ? 1 : 0)
Button(action: {
isShowText = true
}, label: {
Text("Animation")
})
}
這個例子有一個按鈕,按鈕按下去之後,會將文字顯示出來。是利用opacity這個屬性來做到,當isShowText為true時,opacity設定為1,就表示為顯示,否則當isShowText為false,opacity設定為0,就表示為不顯示。
顯示如圖:
但透過按鈕的顯示方式為直接顯示,在UI上來講不是那麼自然,所以就可以加入動畫來讓顯示畫面自然許多,例如:
Button(action: {
withAnimation(.easeInOut(duration: 1)) {
isShowText.toggle()
}
}, label: {
Text("Animation")
})
在要設定值的地方,加入withAnimation這個動畫指令。在這個例子是因為要控制isShowText這個變數,所以用withAnimation將其包覆,並且設定動畫的屬性為easeInOut,且動畫時間為1秒。
顯示如圖:
所以透過動畫指令,就可以實作彈跳視窗,例如:
ZStack {
Button(action: {
withAnimation(.easeInOut(duration: 0.6)) {
isShowText.toggle()
}
}, label: {
Text("Animation")
})
Text("Hello, World!")
.frame(width: 300, height: 150)
.background(.gray)
.cornerRadius(8)
.opacity(isShowText ? 1 : 0)
}
這裡將文字修改為具有背景的形狀,然後使用ZStack將按鈕與文字重疊再一起。
顯示如圖:
而又另外可以先將文字放在畫面外面,使用offset屬性設定y值可以達到,例如:
@State var yOffset: CGFloat = 600
var body: some View {
ZStack {
Button(action: {
withAnimation(.easeInOut(duration: 0.6)) {
yOffset = 0
}
}, label: {
Text("Animation")
})
Text("Hello, World!")
.frame(width: 300, height: 150)
.background(.gray)
.cornerRadius(8)
.offset(y: yOffset)
}
}
顯示如圖:
而動畫指令除了easeInOut之外,可以更換成spring,就可以顯示具有彈跳的動畫,例如:
Button(action: {
withAnimation(.spring(response: 0.6, dampingFraction: 0.8)) {
yOffset = 0
}
}, label: {
Text("Animation")
})
顯示如圖:
可以去設定dampingFraction的參數值,來達成彈跳的範圍,數值越小,彈跳越大,例如:
withAnimation(.spring(response: 0.6, dampingFraction: 0.4)) {
yOffset = 0
}
顯示如圖:
而一般在實務上,不會直接指定yOffset的值,而是透過目前手機的大小來決定,例如:
@State var yOffset: CGFloat = 0
var body: some View {
GeometryReader { geometry in
ZStack {
Button(action: {
withAnimation(.spring(response: 0.6, dampingFraction: 0.8)) {
yOffset = 0
}
}, label: {
Text("Animation")
})
Text("Hello, World!")
.frame(width: 300, height: 150)
.background(.gray)
.cornerRadius(8)
.offset(y: yOffset)
}
.frame(width: geometry.size.width, height: geometry.size.height)
.onAppear {
yOffset = geometry.size.height
}
}
}
GeometryReader元件可以取得目前手機的大小範圍,透過回傳參數geometry來取得螢幕的寬與高。
onAppear屬性表示在畫面一開始,就會呼叫,所以這裡當畫面一顯示出來,就設定yOffset的值為螢幕的高度,就表示一開始會在畫面之外。
從 SwiftUI 到 Apple Vision Pro - SwiftUI 從零開始 Day17 [完]